package com.itheima.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.dao.SetmealDao;
import com.itheima.dto.SetmealDto;
import com.itheima.entity.Category;
import com.itheima.entity.Setmeal;
import com.itheima.entity.SetmealDish;
import com.itheima.exception.CustomException;
import com.itheima.service.CategoryService;
import com.itheima.service.SetmealDishService;
import com.itheima.service.SetmealService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Tang
 * @date 2023/4/12
 */
@Service
public class SetmealServiceImpl extends ServiceImpl<SetmealDao, Setmeal> implements SetmealService {
    @Autowired
    private SetmealDishService setmealDishService;

    @Autowired
    private CategoryService categoryService;

    /**
     * 新增套餐包含套餐菜品信息
     *
     * @param setmealDto
     */
    @Override
    public void addSetmealWithDish(SetmealDto setmealDto) {
        //0.开启事务（涉及套餐表和套餐菜品表的插入）
        //1.把套餐的基本信息保存到套餐表setmeal中
        this.save(setmealDto);

        //2.把套餐菜品信息保存到套餐菜品关系表setmeal_dish中
        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
        //2.2 关联套餐id
        for (SetmealDish setmealDish : setmealDishes) {
            setmealDish.setSetmealId(setmealDto.getId());
        }
        setmealDishService.saveBatch(setmealDishes);
    }

    /**
     * 分页查询
     *
     * @param page
     * @param pageSize
     * @param name     套餐名称
     * @return
     */
    @Override
    public Page<SetmealDto> getPage(Integer page, Integer pageSize, String name) {
        //0.添加分页拦截器【已完成】
        //1.构造分页对象setmealPage = new Page(page, pageSize)
        Page<Setmeal> setmealPage = new Page<>(page, pageSize);

        //2.构造条件对象，设置查询条件
        LambdaQueryWrapper<Setmeal> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(name != null, Setmeal::getName, name);

        //3.设置排序字段
        wrapper.orderByDesc(Setmeal::getUpdateTime);

        //4.调用自身（mp）的分页查询
        this.page(setmealPage, wrapper);

        //优化===========================
        //a.新建分页对象setmealDtoPage = new Page<SetmealDto>()
        Page<SetmealDto> setmealDtoPage = new Page<>();

        //b.构造setmealDtoPage数据：
        //c.将setmealPage所有的属性值全部拷贝给setmealDtoPage，需要排除records属性
        BeanUtils.copyProperties(setmealPage, setmealDtoPage, "records");

        //d.封装records属性，构造List<SetmealDto>数据
        //e.List<SetmealDto> dtos = new ArrayList<>()
        List<SetmealDto> setmealDtoList = new ArrayList<>();

        //f.借助setmealPage里面的records属性（List<Setmeal>）
        List<Setmeal> setmealList = setmealPage.getRecords();

        //g.循环遍历List<Setmeal>
        for (Setmeal setmeal : setmealList) {
            SetmealDto setmealDto = new SetmealDto();
            //将setmeal所有的属性值拷贝SetmealDto
            BeanUtils.copyProperties(setmeal, setmealDto);
            //h.查询分类表category获取分类名称（根据分类id），将分类名称封装到SetmealDto，将SetmealDto添加到dtos
            Category category = categoryService.getById(setmeal.getCategoryId());
            if (category != null) {
                setmealDto.setCategoryName(category.getName());
            }else {
                setmealDto.setCategoryName("未知类型");
            }
            //将setmealDto添加到setmealList
            setmealDtoList.add(setmealDto);
        }

        //i.将records属性设置回到setmealDtoPage
        setmealDtoPage.setRecords(setmealDtoList);

        //5.返回结果setmealPage
        return setmealDtoPage;
    }

    /**
     * 删除套餐
     * @param ids
     */
    @Override
    public void removeWithDish(List<Long> ids) {
        //0.开启事务（涉及多表删除）
        //1.查询套餐表，判断套餐的状态是否是售卖中，如果售卖中，应该禁止删除
        List<Setmeal> setmeals = this.listByIds(ids);
        for (Setmeal setmeal : setmeals) {
            if (setmeal.getStatus() == 1) { //1代表售卖中，应该禁止删除
                throw new CustomException("该套餐正在售卖中，禁止删除！");
            }
        }

        //2.调用自身(mp)的删除方法 (逻辑删除)
        this.removeByIds(ids);

        //3.根据套餐id删除套餐菜品关系表数据
        LambdaQueryWrapper<SetmealDish> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SetmealDish::getSetmealId, ids);  //where setmeal_id in (xxx,xx,xxx,xx )
        setmealDishService.remove(wrapper);
    }
/*
* 修改套餐*/
    @Override
    public void updateWithDish(SetmealDto setmealDto) {
//保存setmeal表中的基本数据
    this.updateById(setmealDto);
// 先删除原来的套餐所对应的菜品数据。
        LambdaQueryWrapper<SetmealDish>queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(SetmealDish::getSetmealId,setmealDto.getId());
        setmealDishService.remove(queryWrapper);
        // 更新套餐关联菜品信息。setmeal_dish表。
        // Field 'setmeal_id' doesn't have a default value] with root cause
        // 所以需要处理setmeal_id字段。
        // 先获得套餐所对应的菜品集合。
        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
        //每一个item为SetmealDish对象。
        setmealDishes=setmealDishes.stream().peek((item) -> {
            //设置setmeal_id字段。
            item.setSetmealId(setmealDto.getId());
        }).collect(Collectors.toList());

//重新保存套餐对应的菜品数据
        setmealDishService.saveBatch(setmealDishes);

    }
}
